package com.qf.thread.compalate;

import java.util.concurrent.*;

public class WhenCompleteDemo {

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 创建一个线程池
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                5,
                20,
                2000,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<Runnable>(10000),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy()
        );

        // 启动一个线程计算结果，最后把结果返回
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            int sum = 0;
            for (int i = 0; i < 10; i++) {
                sum += i;
//                try {
//                    Thread.sleep(200);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
            }
            System.out.println("线程1:计算结果:" + Thread.currentThread().getName());
//            int i = 10 / 0;
            return "sum:" + sum;
        }, executor);

        // 上面的线程执行结束后调用
        // resp:上一个线程的返回结果=
        // exc:上一个线程的异常对象(上一个线程中抛出了异常
//        future.whenComplete((resp, exc) -> {
//            System.out.println("线程1执行结束:" + Thread.currentThread().getName() + ",返回结果是:" + resp + "，线程1抛出的异常:" + exc);
//            if (exc == null) {
//                System.out.println("上面的线程执行没有异常，后面按照业务接着往后处理");
//            } else {
//                System.out.println("上面的线程执出现了异常，后面按照业务接着往后处理");
//            }
//        });

        // 线程1执行完后，从线程池中再申请一个线程来执行本次的任务
        CompletableFuture<String> exceptionally = future.whenCompleteAsync((resp, exec) -> {
            System.out.println("线程1执行完后，从线程池中再申请一个线程来执行本次的任务：" + Thread.currentThread().getName());
            System.out.println("resp:" + resp + ",exec:" + exec);
        }, executor)
                .exceptionally((resp) -> {
                    System.out.println("线程1中出现异常后执行:" + Thread.currentThread().getName());
                    return "200";
                });

        String s = exceptionally.get();
        System.out.println("降级的值：" + s);

        System.out.println("---------------------------------------");

        CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
            int sum = 10 / 5;
            return "sum:" + sum;
        }, executor) // 启动一个先从去做计算任务
                .whenCompleteAsync((resp, exc) -> { // 上线线程计算完成，在申请一个线程执行这个任务
                    //resp:上一个线程的返回结果
                    // exc:抛出的异常
                }, executor).exceptionally((resp) -> { // 上面那个线程运行出现异常后会调用这个方法，这个方法可以做降级
                    // resp:上一个线程的返回结果
                    return "200;";
                });

    }
}
